﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace IFramework
{
    public static partial class StringExtension
    {
        public static string[] GetDirSubDirs(this string self)
        {
            var di = new DirectoryInfo(self);
            var dirs = di.GetDirectories();
            return dirs.Select(d => d.Name).ToArray();
        }
        public static List<string> GetSubFiles(this string self, bool isAll = true, string suffix = "")
        {
            List<string> pathList = new List<string>();
            DirectoryInfo info = new DirectoryInfo(self);
            if (!info.Exists)
            {
                return pathList;
            }
            var files = info.GetFiles();
            foreach (var fi in files)
            {
                if (!string.IsNullOrEmpty(suffix))
                {
                    if (!fi.FullName.EndsWith(suffix, System.StringComparison.CurrentCultureIgnoreCase))
                    {
                        continue;
                    }
                }
                pathList.Add(fi.FullName);
            }
            if (isAll)
            {
                var dirs = info.GetDirectories();
                foreach (var d in dirs)
                {
                    pathList.AddRange(GetSubFiles(d.FullName, isAll, suffix));
                }
            }
            return pathList;
        }

        public static bool IsDirectory(this string self)
        {
            FileInfo fi = new FileInfo(self);
            if ((fi.Attributes & FileAttributes.Directory) != 0)
                return true;
            return false;
        }
        public static void ClearDir(this string self)
        {
            if (Directory.Exists(self))
            {
                Directory.Delete(self, true);
            }
            Directory.CreateDirectory(self);
        }
        public static bool RemoveEmptyDirectory(this string self)
        {
            if (string.IsNullOrEmpty(self))
            {
                throw new Exception("Directory name is invalid.");
            }
            try
            {
                if (!Directory.Exists(self))
                {
                    return false;
                }
                // 不使用 SearchOption.AllDirectories，以便于在可能产生异常的环境下删除尽可能多的目录
                string[] subDirectoryNames = Directory.GetDirectories(self, "*");
                int subDirectoryCount = subDirectoryNames.Length;
                foreach (string subDirectoryName in subDirectoryNames)
                {
                    if (RemoveEmptyDirectory(subDirectoryName))
                    {
                        subDirectoryCount--;
                    }
                }
                if (subDirectoryCount > 0)
                {
                    return false;
                }
                if (Directory.GetFiles(self, "*").Length > 0)
                {
                    return false;
                }
                Directory.Delete(self);
                return true;
            }
            catch
            {
                return false;
            }
        }
        public static string GetParentDir(this string self)
        {
            return Path.GetDirectoryName(self);
        }

        public static string CombinePath(this string self, string toCombinePath)
        {
            return Path.Combine(self, toCombinePath).ToRegularPath();
        }
        public static string CombinePath(this string self,string[] paths)
        {
            for (int i = 1; i < paths.Length; i++)
            {
                self = self.CombinePath(paths[i]);
            }
            return self.ToRegularPath();
        }

        public static string ReadText(this string self)
        {
            var result = string.Empty;
            using (var fs = new FileStream(self, FileMode.Open, FileAccess.Read))
            {
                using (var sr = new StreamReader(fs))
                {
                    result = sr.ReadToEnd();
                }
            }
            return result;
        }
        public static void WriteText(this string self, string content)
        {
            using (var fs = new FileStream(self, FileMode.Open, FileAccess.Read))
            {
                using (StreamWriter sw = new StreamWriter(fs))
                {
                    fs.Lock(0, fs.Length);
                    sw.Write(content);
                    fs.Unlock(0, fs.Length);
                    sw.Flush();
                    sw.Close();
                    fs.Flush();
                    fs.Close();
                }
            }
        }

        public static string GetFileName(this string self)
        {
            self = self.ToRegularPath();
            var lastIndex = self.LastIndexOf("/");
            return lastIndex >= 0 ? self.Substring(lastIndex + 1) : self;
        }
        public static string GetFileNameWithoutExtend(this string self)
        {
            var fileName = GetFileName(self);
            var lastIndex = fileName.LastIndexOf(".");

            return lastIndex >= 0 ? fileName.Substring(0, lastIndex) : fileName;
        }
        public static string GetFileExtendName(this string self)
        {
            var lastIndex = self.LastIndexOf(".");
            if (lastIndex >= 0)
            {
                return self.Substring(lastIndex);
            }
            return string.Empty;
        }

        public static string GetDirPath(this string self)
        {
            self = self.ToRegularPath();
            var lastIndex = self.LastIndexOf("/");
            return self.Substring(0, lastIndex + 1);
        }
        public static string GetLastDirName(this string self)
        {
            self = self.ToRegularPath();
            var dirs = self.Split('/');
            return dirs[dirs.Length - 2];
        }
        public static string ToRegularPath(this string self)
        {
            self = self.Replace('\\', '/');
            return self;
        }
        public static string ToRemotePath(this string self)
        {
            self = self.ToRegularPath();
            return self.Contains("://") ? self : ("file:///" + self).Replace("file:////", "file:///");
        }

    }
}
